package com.ckjava.web.base;

import com.ckjava.entity.base.BaseMybatisEntity;
import com.ckjava.entity.base.PageParamer;
import com.ckjava.service.base.BaseMybatisCrudService;
import com.ckjava.xutils.Constants;
import com.ckjava.xutils.JsonUtils;
import com.ckjava.xutils.http.HttpResponse;
import com.ckjava.xutils.http.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Api
public abstract class BaseMybatisCrudController<S extends BaseMybatisCrudService, E extends BaseMybatisEntity> implements Constants {

    private static final Logger logger = LoggerFactory.getLogger(BaseMybatisCrudController.class);

    @Autowired
    public S service;

    @ApiOperation("根据 id 获取一个对象")
    @GetMapping("/{id}")
    public HttpResponse<E> get(
            @PathVariable Long id) {

        AtomicReference<E> atomicReference = new AtomicReference<>();
        service.get(id).ifPresent(data -> atomicReference.set((E) data));

        return HttpResponse.getReturn(atomicReference.get(), HTTPCODE.code_200, null);
    }

    @ApiOperation("根据字段值查询")
    @GetMapping("/byParams")
    public HttpResponse<List<E>> getParams(
            @ModelAttribute E e) {

        AtomicReference<List<E>> atomicReference = new AtomicReference<>();
        service.getByParam(e).ifPresent(data -> atomicReference.set((List<E>) data));

        return HttpResponse.getReturn(atomicReference.get(), HTTPCODE.code_200, null);
    }

    @ApiOperation("获取所有的对象")
    @GetMapping(value = "/all")
    public HttpResponse<List<E>> findAll() {

        AtomicReference<List<E>> atomicReference = new AtomicReference<>();
        service.getAll().ifPresent(list -> atomicReference.set((List<E>) list));

        return HttpResponse.getReturn(atomicReference.get(), HTTPCODE.code_200, null);
    }

    @ApiOperation("保存或者修改一个对象")
    @PostMapping
    public HttpResponse<Long> saveOrUpdate(
            @RequestBody E e) {
        return HttpResponse.getReturn((Long) service.saveOrUpdate(e).get(), HTTPCODE.code_200, null);
    }

    @ApiOperation("根据 id 删除一个对象")
    @DeleteMapping("/{id}")
    public HttpResponse<Integer> delete(
            @PathVariable Long id) {

        AtomicReference<Integer> atomicReference = new AtomicReference<>();
        service.delete(id).ifPresent(data -> atomicReference.set(Integer.parseInt(data.toString())));

        return HttpResponse.getReturn(atomicReference.get(), HTTPCODE.code_200, null);
    }

    @ApiOperation("分页获取数据")
    @GetMapping(value = "/page")
    public HttpResponse<Page<E>> page(
            @ApiParam("{\n" +
                    "    \"sort\": {\n" +
                    "        \"predicate\": \"id\",\n" +
                    "        \"reverse\": true\n" +
                    "    },\n" +
                    "    \"search\": {\n" +
                    "        \"predicateObject\": {\n" +
                    "            \"name\": \"like,test\"\n" +
                    "        }\n" +
                    "    },\n" +
                    "    \"pagination\": {\n" +
                    "        \"start\": 1,\n" +
                    "        \"totalItemCount\": 0,\n" +
                    "        \"number\": 10,\n" +
                    "        \"numberOfPages\": 2\n" +
                    "    }" +
                    " }\n" +
                    "对于 predicateObject 中的参数，如果 activity=false, 传参为： \"activity\": \"=,false\"，" +
                    "如果 activity like '%false%', 传参为 \"activity\": \"like,false\"" +
                    "}")
            @RequestParam String params) {

        PageParamer pageParamer = JsonUtils.readJavaObject(params, PageParamer.class).orElse(null);

        AtomicReference<Page<E>> atomicReference = new AtomicReference<>();
        service.getPage(pageParamer).ifPresent(data -> atomicReference.set((Page<E>) data));

        return HttpResponse.getReturn(atomicReference.get(), HTTPCODE.code_200, null);

    }
}
